//License: Artistic License v2.0, http://opensource.org/licenses/Artistic-2.0

/*
	A minimalistic inter-server messaging.  First written as netchan until it was deprecated in Go1.
*/
package main

import (
	"encoding/csv"
	"encoding/gob"
	"log"
	"net"
	"os"
	"time"
)

//SetListener sets up inbound queue at connType, connAddr.
func SetListener(connType, connAddr string, wait int) (listener net.Listener) {
	var err error
	for {
		listener, err = net.Listen(connType, connAddr)
		if err != nil {
			log.Println(err)
			log.Printf("Retrying ... in ~ %ds\n", wait)
			time.Sleep(time.Duration(wait) * time.Second)
		} else {
			break
		}
	}
	return listener
}

func SendMsg(msg []string, connType, connAddr string) {
	conn, err := net.Dial(connType, connAddr)
	if err != nil {
		log.Println(err)
	} else {
		encoder := gob.NewEncoder(conn)
		err = encoder.Encode(msg)
		if err != nil {
			log.Println(err)
		}
		conn.Close()
	}
}

func GetMsg(listener *net.Listener) (msg []string) {
	conn, err := (*listener).Accept()
	if err != nil {
		log.Println(err)
	}
	decoder := gob.NewDecoder(conn)
	err = decoder.Decode(&msg)
	if err != nil {
		log.Println(err)
	}
	conn.Close()
	return msg
}

//SaveToFile writes messages ([]string) sent over the queue to file(s) saved in folderPath.
//
//The size per file is defined by bufSize (cannot be too small or the
//incoming would be too fast before it checks the loop boundary).
//When it reaches the planned size, the file is closed and the next file is created.
//writeImmediately determines whether to write every message that comes through
//the queue (i.e. ensures everything is written, but this is disk-bound performance) or
//to write only when it has received bufSize number of messages (i.e. if server is stopped,
//then some messages that are still in buffer are not written to disk).
//Pre-requisite: You must establish channel beforehand via SetListener!
func SaveToFile(listener *net.Listener,
	folderPath, fileName, fileType string, bufSize int, writeImmediately bool) {
	var msg []string
	for {
		var f os.File = newLog(folderPath, fileName, fileType)
		if fileType == "csv" {
			csvLog := csv.NewWriter(&f)
			for i := 0; i < bufSize; i++ {
				msg = GetMsg(listener) //
				csvLog.Write(msg)
				if writeImmediately {
					csvLog.Flush()
				}
			}
			if !writeImmediately {
				csvLog.Flush()
			}
		} //else other file types - future feature
		f.Close() //need to specifically close now, not defer, in case of high traffic
	}
}

func ToSlice(a ...string) []string {
	return a
}

//Copyright: Slamet Hendry
